package main

import "fmt"

func main() {
	//channel的定义
	//var关键字 变量名 = make(chan 类型， 长度)
	var ch1 = make(chan int, 3)
	var ch2 = make(chan bool, 2)
	var ch3 = make(chan string, 3)
	fmt.Println(ch1, ch2, ch3)
	//channel的操作
	//往channel中写元素
	ch1 <- 5
	ch1 <- 10
	ch1 <- 15
	//从channel中读取元素
	num1 := <-ch1
	num2 := <-ch1
	num3 := <-ch1
	fmt.Println(num1, num2, num3)
	//死锁发生的场景
	//1、当channel长度满了，继续写，则会死锁
	ch2 <- true
	ch2 <- false
	//2、当channel里面没有值了，继续读，会死锁
	//num4 := <- ch1
	//fmt.Println(num4)

	//优雅的从channel中取值
	ch4 := make(chan int, 5)
	ch4 <- 10
	ch4 <- 10
	ch4 <- 10
	ch4 <- 10
	ch4 <- 10
	//内置方法，用于关闭channel
	//能close则close，因为close的好处较多，可以避免发生死锁
	close(ch4)
	//通道关闭且读完后会自动退出for循环，不会死锁，若不close则会死锁
	for i := range ch4 {
		fmt.Println(i)
	}
	//通道关闭后，可以继续读取，读完后继续读都是零值类型
	num5 := <-ch4
	fmt.Println(num5)

}
